package jxtcp

import (
	"bufio"
	"fmt"
	"net"
	"sync"
	"sync/atomic"
)

type ServerConn struct {
	id         string
	conn       net.Conn
	onMessage  func(m *Message)
	onClose    func(id string)
	static     int32
	stopChan   chan struct{}
	sendLocker sync.Mutex
	writer     *bufio.Writer
	reader     *bufio.Reader
	MachineId  uint32
}

func NewServerConn(id string, conn net.Conn, onmessage func(m *Message), onclose func(id string)) *ServerConn {
	outData := &ServerConn{
		id:        id,
		conn:      conn,
		onMessage: onmessage,
		onClose:   onclose,
		stopChan:  make(chan struct{}),
		static:    2,
		writer:    bufio.NewWriter(conn),
		reader:    bufio.NewReader(conn),
	}
	outData.init()
	return outData
}
func (c *ServerConn) init() {
	go c.readLoop()
}
func (c *ServerConn) readLoop() {
	defer close(c.stopChan)
	for {
		select {
		case <-c.stopChan:
			c.conn.Close()
			c.onClose(c.id)
			return
		default:
			m, err := ReadMessage(c.reader)
			if err != nil {
				fmt.Println("读取数据错误", err.Error())
				c.conn.Close()
				c.onClose(c.id)
				return
			}
			if m.Type == 10 {
				c.MachineId = m.MachineId
			} else {
				if c.onMessage != nil {
					go c.onMessage(m)
				}
			}
		}
	}
}
func (c *ServerConn) Static() int32 {
	return atomic.LoadInt32(&c.static)
}
func (c *ServerConn) SendMessage(m *Message) (bool, error) {
	c.sendLocker.Lock()
	defer c.sendLocker.Unlock()
	if atomic.LoadInt32(&c.static) == 2 {
		return true, c.sendMessage(m)
	}
	return false, nil
}
func (c *ServerConn) sendMessage(m *Message) error {
	atomic.StoreInt32(&c.static, 1)
	defer func() {
		atomic.StoreInt32(&c.static, 2)
	}()
	err := m.WriteMessage(c.writer)
	if err != nil {
		return err
	}
	return nil
}
